/*
 * Android Runner is a multiplayer GPS game fully written by Xurxo Mendez Perez
 * 
 * Copyright (C) 2009 Xurxo Mendez Perez
 *   
 * This file is part of Android Runner.
 * 
 * Android Runner is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * Android Runner is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with Android Runner.  If not, see <http://www.gnu.org/licenses/>.
 */

package es.sonxurxo.gpsgame.client.cv.activity;

import android.app.Activity;
import android.app.Dialog;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import es.sonxurxo.gpsgame.client.R;
import es.sonxurxo.gpsgame.client.cv.common.dialogs.CommonDialogs;
import es.sonxurxo.gpsgame.client.cv.util.constants.CustomResultCodes;
import es.sonxurxo.gpsgame.client.model.service.player.HttpPlayerServiceImpl;
import es.sonxurxo.gpsgame.client.model.service.to.Player;
import es.sonxurxo.gpsgame.client.util.exception.ServerException;

/**
 * 
 * @author "Xurxo Mendez Perez"
 *
 */
public class LoginActivity extends Activity {

    private static final int REGISTER_ID = Menu.FIRST;
    private static final int LOGIN_ID = Menu.FIRST + 1;
    
    private static final int PLAYER_INFO_REQUEST_CODE = 0;
    private static final int REGISTER_REQUEST_CODE = 1;
    
	private Player player = new Player();
	
	private EditText loginText, passwordText;
	private TextView loginErrorView, passwordErrorView;
	private Button loginButton, registerButton;
	
	private LoginTask loginTask;
	
	/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
        setContentView(R.layout.login_page);
        getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.custom_title_1);
        showSplashScreen();
        loginErrorView = (TextView)findViewById(R.id.lp_tv_login_message);
        passwordErrorView = (TextView)findViewById(R.id.lp_tv_password_message);
        loginText = (EditText)findViewById(R.id.lp_et_login);
        loginText.setOnKeyListener(new OnKeyListener() {

			public boolean onKey(View v, int keyCode, KeyEvent event) {
				if (!loginErrorView.getText().equals(""))
					loginErrorView.setText("");
				return false;
			}
        });
        passwordText = (EditText)findViewById(R.id.lp_et_password);
        passwordText.setOnKeyListener(new OnKeyListener() {

			public boolean onKey(View v, int keyCode, KeyEvent event) {
				if (!passwordErrorView.getText().equals(""))
					passwordErrorView.setText("");
				return false;
			}
        });

        loginButton = (Button)findViewById(R.id.lp_b_login);
        loginButton.setOnClickListener(new OnClickListener() {

			public void onClick(View v) {
				launchLoginThread();
			}
        	
        });
        registerButton = (Button)findViewById(R.id.lp_b_register);
        registerButton.setOnClickListener(new OnClickListener() {

			public void onClick(View v) {
				doRegister();
			}
        	
        });        
        if (getIntent().getExtras() != null) {
        	if (getIntent().getExtras().getSerializable("player") != null) {
            	player = (Player)getIntent().getExtras().getSerializable("player");
            	loginText.setText(player.getLogin());
            }
        }
    }
    
    @Override
	protected void onResume() {
		super.onResume();
		try {
			dismissDialog(CommonDialogs.CONNECTING_TO_SERVER_DIALOG_ID);
		} catch (Exception e) {
			
		}
	}

	private void showSplashScreen() {
    	ImageView imageView = new ImageView(this);
		imageView.setImageResource(R.drawable.splash);
		Toast toast = new Toast(this);
		toast.setView(imageView);
		toast.setGravity(Gravity.CENTER, 0, 0);
		toast.setDuration(Toast.LENGTH_SHORT);
		toast.show();
    }

	private void launchLoginThread() {
			String login = loginText.getText().toString();
			String password = passwordText.getText().toString();

			if (login.equals("")) {
				loginErrorView.setText("This field can't be empty.");
				return;
			}
			else if (password.equals("")) {
				passwordErrorView.setText("This field can't be empty.");
				return;
			}

			loginTask = new LoginTask(login, password);
			Thread loginThread = new Thread(null, loginTask, "Login");
			loginThread.start();
			showDialog(CommonDialogs.CONNECTING_TO_SERVER_DIALOG_ID);
    }
	
	private void doLogin() {
		Intent i = new Intent(LoginActivity.this, MainMenuActivity.class);
    	i.putExtra("player", player);
        startActivityForResult(i, PLAYER_INFO_REQUEST_CODE);
	}

    private void doRegister() {
    	Intent i = new Intent(this, RegisterPlayerActivity.class);
		startActivityForResult(i, REGISTER_REQUEST_CODE);
    }

    @Override
    protected Dialog onCreateDialog(int id) {
    	return CommonDialogs.createDialog(id, this);
    }
    
	@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        menu.add(0, REGISTER_ID,0, R.string.lp_b_register).setIcon(R.drawable.register);
        menu.add(0, LOGIN_ID,0, R.string.lp_b_login).setIcon(R.drawable.login);
        return true;
    }
    
    @Override
    public boolean onMenuItemSelected(int featureId, MenuItem item) {
        switch(item.getItemId()) {
        case LOGIN_ID:
        	launchLoginThread();
        	break;
        case REGISTER_ID:
        	doRegister();
        	break;
        }
        
        return super.onMenuItemSelected(featureId, item);
    }

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		switch(requestCode) {
		case REGISTER_REQUEST_CODE:
			switch(resultCode) {
			case RESULT_CANCELED:
				break;
			case CustomResultCodes.LOGOUT_RESULT_CODE:
				loginText.setText("");
				passwordText.setText("");
				break;
			}
			break;
		case PLAYER_INFO_REQUEST_CODE:
			switch (resultCode) {
			case CustomResultCodes.LOGOUT_RESULT_CODE:
				loginText.setText("");
				passwordText.setText("");
				break;
			}
			break;
		}
	}
	
	private class LoginHandler extends Handler {

		public LoginHandler(Looper looper) {
			super(looper);
		}
		
		@Override
		public void handleMessage(Message msg) {
			ServerException sE = 
				(ServerException)msg.getData().getSerializable("ServerException");
			if (sE	!= null) {
				dismissDialog(CommonDialogs.CONNECTING_TO_SERVER_DIALOG_ID);
	        	CommonDialogs.errorMessage = sE.getMessage();
	        	String message = new String();
	        	switch(sE.getCode()) {
	        	case ServerException.DUPLICATE_INSTANCE_CODE:
	        		message = (String)getString(R.string.error_login_exists_message);
	        		loginErrorView.setText(message);
	        		break;
	        	case ServerException.INCORRECT_PASSWORD_CODE:
	        		message = (String)getString(R.string.error_incorrect_password_message);
	        		passwordErrorView.setText(message);
	        		break;
	        	case ServerException.INSTANCE_NOT_FOUND_CODE:
	        		message = (String)getString(R.string.error_instance_not_found_message);
	        		loginErrorView.setText(message);
	        		break;
	        	case ServerException.SERVER_OFFLINE_CODE:
	        		showDialog(CommonDialogs.SERVER_OFFLINE_DIALOG_ID);
	        		break;
	        	case ServerException.EXCEPTION_CODE:
	        		showDialog(CommonDialogs.SERVER_ERROR_DIALOG_ID);
	        		break;
	        	}
	        	return;
	        }
        	Exception e = 
	        	(Exception)msg.getData().getSerializable("Exception");
	        	if (e != null) {
	        		dismissDialog(CommonDialogs.CONNECTING_TO_SERVER_DIALOG_ID);
	        		CommonDialogs.errorMessage = e.getMessage();
		        	showDialog(CommonDialogs.CLIENT_ERROR_DIALOG_ID);
		        	return;
	        	}
			player = (Player)msg.getData().getSerializable("player");
			doLogin();
		}
		
	}
	
	private class LoginTask implements Runnable {

		String login, password;
		HttpPlayerServiceImpl playerService;
		
		LoginTask(String login, String password) {
			this.login = login;
			this.password = password;
			playerService = new HttpPlayerServiceImpl();
		}
		
		public void run() {
			
			LoginHandler handler = new LoginHandler(Looper.getMainLooper());
			Bundle data = new Bundle();
			Message msg = new Message();
			try {
				Player player = playerService.loginPlayer(login, password);
				data.putSerializable("player", player);
				msg.setData(data);
				handler.sendMessage(msg);
				
			} catch (ServerException e) {
	        	data.putSerializable("ServerException", e);
	        	msg.setData(data);
				handler.sendMessage(msg);
	        } catch (Exception e) {
	        	data.putSerializable("Exception", e);
	        	msg.setData(data);
				handler.sendMessage(msg);
	        }
		}
	}
}
